home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 026-050 / 042 / mg1a / symbol.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  15KB  |  489 lines

  1. /*
  2.  * Symbol tables, and keymap setup.
  3.  * The terminal specific parts of building the
  4.  * keymap has been moved to a better place.
  5.  */
  6. #include    "def.h"
  7.  
  8. #ifdef    HASH
  9. Since you're seeing this, you must have defined HASH to try and get the
  10. hashing code back. You're getting an error because I (mwm@ucbvax) want you
  11. to read this.
  12.  
  13. With the change in function completion, there is at least one linear search
  14. through the function list for every hash lookup (ignoring the startup code).
  15. Given that there are probably actually MANY more linear searches for
  16. completion than fullname lookups, some structure other than a hash table is
  17. better suited to this purpose. I suggest trying sorting the lists for more
  18. speed, then going to a binary search tree, and finally going to a trie.
  19. #endif    HASH
  20.  
  21. /*
  22.  * Defined here so to collect the #ifdef MEYN config stuff in one file
  23.  * If you set either MINDENT or MFILL, then you need to change the bindings
  24.  * in this file to match: KCTRL|'M' -> newline-and-indent and KCTRL|'J' ->
  25.  * insert-newline for MINDENT, and ' ' -> insert-with-wrap for MFILL.
  26.  * MEYN is used for compile-time customization of the system for micros.
  27.  */
  28. #ifndef    MEYN
  29. int    mode = 0;            /* All modes off        */
  30. #else
  31. int    mode = MBSMAP|MINDENT;
  32. #endif
  33.  
  34. /*
  35.  * Defined by "main.c".
  36.  */
  37. extern    int    ctrlg();        /* Abort out of things        */
  38. extern    int    quit();            /* Quit                */
  39. extern    int    ctlxlp();        /* Begin macro            */
  40. extern    int    ctlxrp();        /* End macro            */
  41. extern    int    ctlxe();        /* Execute macro        */
  42. extern  int    showversion();        /* Show version numbers, etc.    */
  43.  
  44. /*
  45.  * Defined by "search.c".
  46.  */
  47. extern    int    forwsearch();        /* Search forward        */
  48. extern    int    backsearch();        /* Search backwards        */
  49. extern  int    searchagain();        /* Repeat last search command    */
  50. extern  int    forwisearch();        /* Incremental search forward    */
  51. extern  int    backisearch();        /* Incremental search backwards    */
  52. extern  int    queryrepl();        /* Query replace        */
  53.  
  54. /*
  55.  * Defined by "basic.c".
  56.  */
  57. extern    int    gotobol();        /* Move to start of line    */
  58. extern    int    backchar();        /* Move backward by characters    */
  59. extern    int    gotoeol();        /* Move to end of line        */
  60. extern    int    forwchar();        /* Move forward by characters    */
  61. extern    int    gotobob();        /* Move to start of buffer    */
  62. extern    int    gotoeob();        /* Move to end of buffer    */
  63. extern    int    forwline();        /* Move forward by lines    */
  64. extern    int    backline();        /* Move backward by lines    */
  65. extern    int    forwpage();        /* Move forward by pages    */
  66. extern    int    backpage();        /* Move backward by pages    */
  67. extern    int    pagenext();        /* Page forward next window    */
  68. extern    int    setmark();        /* Set mark            */
  69. extern    int    swapmark();        /* Swap "." and mark        */
  70. extern    int    gotoline();        /* Go to a specified line.    */
  71.  
  72. /*
  73.  * Defined by "buffer.c".
  74.  */
  75. extern    int    listbuffers();        /* Display list of buffers    */
  76. extern    int    usebuffer();        /* Switch a window to a buffer    */
  77. extern    int    poptobuffer();        /* Other window to a buffer    */
  78. extern    int    killbuffer();        /* Make a buffer go away.    */
  79. extern    int    savebuffers();        /* Save unmodified buffers    */
  80. extern    int    bufferinsert();        /* Insert buffer into another    */
  81. extern    int    notmodified();        /* Reset modification flag    */
  82.  
  83. #ifdef    DIRLIST
  84. /*
  85.  * Defined by "dirlist.c".
  86.  */
  87. extern    int    dirlist();        /* Directory list.        */
  88. #endif
  89.  
  90. /*
  91.  * Defined by "file.c".
  92.  */
  93. extern    int    filevisit();        /* Get a file, read write    */
  94. extern    int    poptofile();        /* Get a file, other window    */
  95. extern    int    filewrite();        /* Write a file            */
  96. extern    int    filesave();        /* Save current file        */
  97. extern    int    fileinsert();        /* Insert file into buffer    */
  98.  
  99. /*
  100.  * Defined by "match.c"
  101.  */
  102. extern    int    blinkparen();        /* Fake blink-matching-paren var */
  103. extern    int    showmatch();        /* Hack to show matching paren     */
  104.  
  105. /*
  106.  * Defined by "random.c".
  107.  */
  108. extern    int    selfinsert();        /* Insert character        */
  109. extern    int    showcpos();        /* Show the cursor position    */
  110. extern    int    twiddle();        /* Twiddle characters        */
  111. extern    int    quote();        /* Insert literal        */
  112. extern    int    openline();        /* Open up a blank line        */
  113. extern    int    newline();        /* Insert CR-LF            */
  114. extern    int    deblank();        /* Delete blank lines        */
  115. extern    int    delwhite();        /* Delete extra whitespace    */
  116. extern    int    indent();        /* Insert CR-LF, then indent    */
  117. extern    int    forwdel();        /* Forward delete        */
  118. extern    int    backdel();        /* Backward delete in        */
  119. extern    int    killline();        /* Kill forward            */
  120. extern    int    yank();            /* Yank back from killbuffer.    */
  121. extern    int    bsmapmode();        /* set bsmap mode        */
  122. extern    int    flowmode();        /* set flow mode        */
  123. extern    int    indentmode();        /* set auto-indent mode        */
  124. extern    int    fillmode();        /* set word-wrap mode        */
  125.  
  126. /*
  127.  * Defined by "region.c".
  128.  */
  129. extern    int    killregion();        /* Kill region.            */
  130. extern    int    copyregion();        /* Copy region to kill buffer.    */
  131. extern    int    lowerregion();        /* Lower case region.        */
  132. extern    int    upperregion();        /* Upper case region.        */
  133. #ifdef    PREFIXREGION
  134. extern    int    prefixregion();        /* Prefix all lines in region    */
  135. extern    int    setprefix();        /* Set line prefix string    */
  136. #endif
  137.  
  138. /*
  139.  * Defined by "spawn.c".
  140.  */
  141. extern    int    spawncli();        /* Run CLI in a subjob.        */
  142. #ifdef    VMS
  143. extern    int    attachtoparent();    /* Attach to parent process    */
  144. #endif
  145.  
  146. /*
  147.  * Defined by "window.c".
  148.  */
  149. extern    int    reposition();        /* Reposition window        */
  150. extern    int    refresh();        /* Refresh the screen        */
  151. extern    int    nextwind();        /* Move to the next window    */
  152. extern  int    prevwind();        /* Move to the previous window    */
  153. extern    int    onlywind();        /* Make current window only one    */
  154. extern    int    splitwind();        /* Split current window        */
  155. extern    int    delwind();        /* Delete current window    */
  156. extern    int    enlargewind();        /* Enlarge display window.    */
  157. extern    int    shrinkwind();        /* Shrink window.        */
  158.  
  159. /*
  160.  * Defined by "word.c".
  161.  */
  162. extern    int    backword();        /* Backup by words        */
  163. extern    int    forwword();        /* Advance by words        */
  164. extern    int    upperword();        /* Upper case word.        */
  165. extern    int    lowerword();        /* Lower case word.        */
  166. extern    int    capword();        /* Initial capitalize word.    */
  167. extern    int    delfword();        /* Delete forward word.        */
  168. extern    int    delbword();        /* Delete backward word.    */
  169.  
  170. /*
  171.  * Defined by "extend.c".
  172.  */
  173. extern    int    extend();        /* Extended commands.        */
  174. extern    int    desckey();        /* Help key.            */
  175. extern    int    bindtokey();        /* Modify key bindings.        */
  176. extern    int    unsetkey();        /* Unbind a key.        */
  177. extern    int    wallchart();        /* Make wall chart.        */
  178. #ifdef    STARTUP
  179. extern    int    evalexpr();        /* Extended commands (again)    */
  180. extern    int    evalbuffer();        /* Evaluate current buffer    */
  181. extern    int    evalfile();        /* Evaluate a file        */
  182. #endif
  183.  
  184. /*
  185.  * defined by "paragraph.c" - the paragraph justification code.
  186.  */
  187. extern    int    gotobop();        /* Move to start of paragraph.    */
  188. extern    int    gotoeop();        /* Move to end of paragraph.    */
  189. extern    int    fillpara();        /* Justify a paragraph.        */
  190. extern    int    killpara();        /* Delete a paragraph.        */
  191. extern    int    setfillcol();        /* Set fill column for justify.    */
  192. extern    int    fillword();        /* Insert char with word wrap.    */
  193.  
  194. /*
  195.  * defined by prefix.c
  196.  */
  197. extern    int    help();            /* Parse help key.        */
  198. extern    int    ctlx4hack();        /* Parse a pop-to key.        */
  199.  
  200. typedef    struct    {
  201.     KEY    k_key;            /* Key to bind.            */
  202.     int    (*k_funcp)();        /* Function.            */
  203.     char    *k_name;        /* Function name string.    */
  204. }    KEYTAB;
  205.  
  206. /*
  207.  * Default key binding table. This contains
  208.  * the function names, the symbol table name, and (possibly)
  209.  * a key binding for the builtin functions. There are no
  210.  * bindings for C-U or C-X. These are done with special
  211.  * code, but should be done normally.
  212.  */
  213. KEYTAB    key[] = {
  214. #ifdef    MEYN        /* Add meyer's peculiar bindings */
  215.     KCTRL|'J',    newline,    "insert-newline",
  216.     KCTRL|'M',    indent,        "newline-and-indent",
  217.     KCTLX|'N',    nextwind,     "next-window",
  218.     KCTLX|'P',    prevwind,    "previous-window",
  219.     KMETA|KCTRL|'C',quit,        "save-buffers-kill-emacs",
  220.     KMETA|KCTRL|'L',refresh,    "redraw-display",
  221.     KMETA|'G',    gotoline,    "goto-line",
  222.     KMETA|'J',    fillpara,    "fill-paragraph",
  223.     KMETA|'Q',    queryrepl,    "query-replace",
  224. #endif
  225.     KCTRL|'@',    setmark,    "set-mark-command",
  226.     KCTRL|'A',    gotobol,    "beginning-of-line",
  227.     KCTRL|'B',    backchar,    "backward-char",
  228.     KCTRL|'D',    forwdel,    "delete-char",
  229.     KCTRL|'E',    gotoeol,    "end-of-line",
  230.     KCTRL|'F',    forwchar,    "forward-char",
  231.     KCTRL|'G',    ctrlg,        "keyboard-quit",
  232.     KCTRL|'H',    help,        "help",
  233.     KCTRL|'I',    selfinsert,    "self-insert-command",
  234. #ifndef    MEYN
  235.     KCTRL|'J',    indent,        "newline-and-indent",
  236. #endif
  237.     KCTRL|'L',    reposition,    "recenter",
  238.     KCTRL|'K',    killline,    "kill-line",
  239. #ifndef    MEYN
  240.     KCTRL|'M',    newline,    "insert-newline",
  241. #endif
  242.     KCTRL|'N',    forwline,    "next-line",
  243.     KCTRL|'O',    openline,    "open-line",
  244.     KCTRL|'P',    backline,    "previous-line",
  245.     KCTRL|'Q',    quote,        "quoted-insert",
  246.     KCTRL|'R',    backisearch,    "isearch-backward",
  247.     KCTRL|'S',    forwisearch,    "isearch-forward",
  248.     KCTRL|'T',    twiddle,    "transpose-chars",
  249.     KCTRL|'V',    forwpage,    "scroll-up",
  250.     KCTRL|'W',    killregion,    "kill-region",
  251.     KCTRL|'Y',    yank,        "yank",
  252. #ifdef    VMS
  253.     KCTRL|'Z',    attachtoparent,    "suspend-emacs",
  254. #else
  255.     KCTRL|'Z',    spawncli,    "suspend-emacs",
  256. #endif
  257.     KCTLX|KCTRL|'B',listbuffers,    "list-buffers",
  258. #ifndef    MEYN
  259.     KCTLX|KCTRL|'C',quit,        "save-buffers-kill-emacs",
  260. #endif
  261. #ifdef    DIRLIST
  262.     KCTLX|KCTRL|'D',dirlist,    "display-directory",
  263. #endif
  264.     KCTLX|KCTRL|'F',filevisit,    "find-file",
  265.     KCTLX|KCTRL|'L',lowerregion,    "downcase-region",
  266.     KCTLX|KCTRL|'O',deblank,    "delete-blank-lines",
  267.     KCTLX|KCTRL|'S',filesave,    "save-buffer",
  268.     KCTLX|KCTRL|'U',upperregion,    "upcase-region",
  269.     KCTLX|KCTRL|'W',filewrite,    "write-file",
  270.     KCTLX|KCTRL|'X',swapmark,    "exchange-point-and-mark",
  271.     KCTLX|'=',    showcpos,    "what-cursor-position",
  272.     KCTLX|'(',    ctlxlp,        "start-kbd-macro",
  273.     KCTLX|')',    ctlxrp,        "end-kbd-macro",
  274.     KCTLX|'^',    enlargewind,    "enlarge-window",
  275.     KCTLX|'0',    delwind,    "delete-window",
  276.     KCTLX|'1',    onlywind,    "delete-other-windows",
  277.     KCTLX|'2',    splitwind,    "split-window-vertically",
  278.     KCTLX|'4',    ctlx4hack,    "ctrlx-four-hack",
  279.     KCTLX|'B',    usebuffer,    "switch-to-buffer",
  280.     KCTLX|'E',    ctlxe,        "call-last-kbd-macro",
  281.     KCTLX|'F',    setfillcol,    "set-fill-column",
  282.     KCTLX|'I',    fileinsert,    "insert-file",
  283.     KCTLX|'K',    killbuffer,    "kill-buffer",
  284.     KCTLX|'S',    savebuffers,    "save-some-buffers",
  285. #ifndef    MEYN
  286.     KCTLX|'O',    nextwind,    "next-window",
  287.     KMETA|'%',    queryrepl,    "query-replace",
  288. #endif
  289.     KMETA|KCTRL|'V',pagenext,    "scroll-other-window",
  290.     KMETA|'>',    gotoeob,    "end-of-buffer",
  291.     KMETA|'<',    gotobob,    "beginning-of-buffer",
  292.     KMETA|'[',    gotobop,    "backward-paragraph",
  293.     KMETA|']',    gotoeop,    "forward-paragraph",
  294.     KMETA|' ',    delwhite,    "just-one-space",
  295.     KMETA|'B',    backword,    "backward-word",
  296.     KMETA|'C',    capword,    "capitalize-word",
  297.     KMETA|'D',    delfword,    "kill-word",
  298.     KMETA|'F',    forwword,    "forward-word",
  299.     KMETA|'L',    lowerword,    "downcase-word",
  300. #ifndef    MEYN
  301.     KMETA|'Q',    fillpara,    "fill-paragraph",
  302. #endif
  303.     KMETA|'R',    backsearch,    "search-backward",
  304.     KMETA|'S',    forwsearch,    "search-forward",
  305.     KMETA|'U',    upperword,    "upcase-word",
  306.     KMETA|'V',    backpage,    "scroll-down",
  307.     KMETA|'W',    copyregion,    "copy-region-as-kill",
  308.     KMETA|'X',    extend,        "execute-extended-command",
  309.     KMETA|'~',    notmodified,    "not-modified",
  310. #ifndef    MEYN
  311.     -1,        prevwind,    "previous-window",
  312.     -1,        refresh,    "redraw-display",
  313.     -1,        gotoline,    "goto-line",
  314. #endif
  315. #ifdef    STARTUP
  316.     -1,        evalexpr,    "eval-expression",
  317.     -1,        evalbuffer,    "eval-current-buffer",
  318.     -1,        evalfile,    "load",
  319. #endif
  320.     -1,        bsmapmode,    "bsmap-mode",
  321.     -1,        flowmode,    "flow-mode",
  322.     -1,        indentmode,    "auto-indent-mode",
  323.     -1,        fillmode,    "auto-fill-mode",
  324.     -1,        fillword,    "insert-with-wrap",
  325.     -1,        shrinkwind,    "shrink-window",
  326.     -1,        searchagain,    "search-again",
  327.     -1,        unsetkey,    "global-unset-key",
  328.     -1,        bindtokey,    "global-set-key",
  329.     -1,        killpara,    "kill-paragraph",
  330.     -1,        showversion,    "emacs-version",
  331.     -1,        blinkparen,    "blink-matching-paren",
  332.     -1,        showmatch,    "blink-matching-paren-hack",
  333.     -1,        bufferinsert,    "insert-buffer",
  334. #ifdef    VMS
  335.     -1,        spawncli,    "push-to-dcl",
  336. #endif
  337. #ifdef    PREFIXREGION
  338.     -1,        prefixregion,    "prefix-region",
  339.     -1,        setprefix,    "set-prefix-string",
  340. #endif
  341.     /* You can actually get to these with keystrokes. See prefix.c */
  342.     -1,        poptobuffer,    "switch-to-buffer-other-window",
  343.     -1,        poptofile,    "find-file-other-window",
  344.     -1,        desckey,    "describe-key-briefly",
  345.     -1,        wallchart,    "describe-bindings",
  346. };
  347.  
  348. #define    NKEY    (sizeof(key) / sizeof(key[0]))
  349.  
  350. /*
  351.  * Symbol table lookup.
  352.  * Return a pointer to the SYMBOL node, or NULL if
  353.  * the symbol is not found.
  354.  */
  355. SYMBOL    *
  356. symlookup(cp) register char *cp; {
  357.     register SYMBOL    *sp;
  358.  
  359. #ifdef    HASH
  360.     sp = symbol[symhash(cp)];
  361. #else
  362.     sp = symbol[0];
  363. #endif
  364.     while (sp != NULL) {
  365.         if (strcmp(cp, sp->s_name) == 0)
  366.             return (sp);
  367. #ifdef    HASH
  368.         if ((sp->s_flags&SFEND) != 0) break;
  369. #endif
  370.         sp = sp->s_symp;
  371.     }
  372.     return (NULL);
  373. }
  374.  
  375. #ifdef    HASH
  376. /*
  377.  * Take a string, and compute the symbol table
  378.  * bucket number. This is done by adding all of the characters
  379.  * together, and taking the sum mod NSHASH. The string probably
  380.  * should not contain any GR characters; if it does the "*cp"
  381.  * may get a nagative number on some machines, and the "%"
  382.  * will return a negative number!
  383.  */
  384. symhash(cp) register char *cp; {
  385.     register int    c;
  386.     register int    n;
  387.  
  388.     n = 0;
  389.     while ((c = *cp++) != 0)
  390.         n += c;
  391.     return (n % NSHASH);
  392. }
  393. #endif
  394.  
  395. /*
  396.  * Build initial keymap. The funny keys
  397.  * (commands, odd control characters) are mapped using
  398.  * a big table and calls to "keyadd". The printing characters
  399.  * are done with some do-it-yourself handwaving. The terminal
  400.  * specific keymap initialization code is called at the
  401.  * very end to finish up. All errors are fatal.
  402.  */
  403. keymapinit() {
  404.     register SYMBOL    *sp;
  405.     register KEYTAB    *kp;
  406.     register int    i;
  407.  
  408.     for (i=0; i<NKEYS; ++i)
  409.         binding[i] = NULL;
  410.     for (kp = &key[0]; kp < &key[NKEY]; ++kp)
  411.         keyadd(kp->k_key, kp->k_funcp, kp->k_name);
  412.     keydup((KEY) (KCTLX|KCTRL|'G'),    "keyboard-quit");
  413.     keydup((KEY) (KMETA|KCTRL|'G'),    "keyboard-quit");
  414.     keyadd((KEY) (KMETA|0x7F), delbword,
  415.                 "backward-kill-word");
  416.     keyadd((KEY) 0x7F, backdel,    "backward-delete-char");
  417.     /*
  418.      * add duplicates (GNU-stuff)
  419.      */
  420.     keydup((KEY) (KCTLX|KCTRL|'Z'), "suspend-emacs");
  421.     /*
  422.      * Should be bound by "tab" already.
  423.      */
  424.     if ((sp=symlookup("self-insert-command")) == NULL)
  425.         panic("no self-insert-command in keymapinit");
  426.     for (i=0x20; i<0x7F; ++i) {
  427.         if (binding[i] != NULL)
  428.             panic("nonull binding in keymapinit");
  429.         binding[i] = sp;
  430.     }
  431.     ttykeymapinit();
  432. #ifdef    HASH
  433.     /* Link up the symbol table entries    */
  434.     for (sp = symbol[i = 0]; i < NSHASH-1; sp = sp->s_symp)
  435.         if (sp->s_symp == NULL) sp->s_symp = symbol[++i];
  436. #endif            
  437. }
  438.  
  439. /*
  440.  * Create a new builtin function "name"
  441.  * with function "funcp". If the "new" is a real
  442.  * key, bind it as a side effect. All errors
  443.  * are fatal.
  444.  */
  445. keyadd(new, funcp, name) register KEY new; int (*funcp)(); char *name; {
  446.     register SYMBOL    *sp;
  447. #ifdef    HASH
  448.     register int    hash;
  449. #endif
  450.  
  451.     if ((sp=(SYMBOL *)malloc(sizeof(SYMBOL))) == NULL)
  452.         panic("No memory");
  453. #ifdef    HASH
  454.     hash = symhash(name);
  455.     if (symbol[hash] == NULL) sp->s_flags |= SFEND;
  456.     sp->s_symp = symbol[hash];
  457.     symbol[hash] = sp;
  458. #else
  459.     sp->s_symp = symbol[0];
  460.         symbol[0] = sp;
  461. #endif
  462.     sp->s_name = name;
  463.     sp->s_funcp = funcp;
  464.     if (new >= 0) {                /* Bind this key.    */
  465.         if (binding[new] != NULL)
  466.             panic("rebinding old symbol");
  467.         binding[new] = sp;
  468.     }
  469. }
  470.  
  471. /*
  472.  * Bind key "new" to the existing
  473.  * routine "name". If the name cannot be found,
  474.  * or the key is already bound, abort.
  475.  */
  476. keydup(new, name) register KEY new; char *name; {
  477.     register SYMBOL    *sp;
  478.  
  479.     if (binding[new]!=NULL || (sp=symlookup(name))==NULL) {
  480. #ifdef    KEYDUP_ERROR
  481.         fprintf (stderr, "keydup: binding[%d] = %x",
  482.                 new, binding[new]);
  483.         fprintf (stderr, " and symlookup(%s) == %x\n", name, sp);
  484. #endif
  485.         panic("keydup");
  486.     }
  487.     binding[new] = sp;
  488. }
  489.